<script setup lang="ts">
import { Delete, Document, FolderOpened } from '@element-plus/icons-vue';
import { invoke } from '@tauri-apps/api/core';
import { ElMessageBox } from 'element-plus';
import { showErrorNotification, showSuccessNotification } from 'my-vue-ui-core/notification';
import { ref } from 'vue';
import { useI18n } from 'vue-i18n';

import FileInfo from '@/features/home/models/file-info';

const props = defineProps<{
  md5: string | number;
  files: FileInfo[];
}>();

const { t } = useI18n();

const formatNumber = new Intl.NumberFormat();
const kbSize = 1024;
const mbSize = kbSize * 1024;
const gbSize = mbSize * 1024;
const tbSize = gbSize * 1024;

const duplicateFiles = ref(props.files);

// Formats file size to friendly info.
function formatSize(size: number): string {
  let calculatedSize = size;
  let denominator = 1;
  let unitType: string;

  if (size < kbSize) {
    unitType = 'B';
  } else if (size < mbSize) {
    denominator = kbSize;
    unitType = 'KB';
  } else if (size < gbSize) {
    denominator = mbSize;
    unitType = 'MB';
  } else if (size < tbSize) {
    denominator = gbSize;
    unitType = 'GB';
  } else {
    denominator = gbSize / 1024;
    unitType = 'TB';
  }

  // Calculates the output size by denominator.
  calculatedSize = size / denominator;

  // Fixes the decimal part to 2 to display only whole numbers.
  const fixedCalculatedSize = parseFloat(calculatedSize.toFixed(2));

  // Formats the output size with the specified number of decimal places.
  return `${formatNumber.format(fixedCalculatedSize)} ${unitType}`;
}

async function openPath(path: String): Promise<void> {
  const result: string = await invoke('open_path', { path: path });

  if (result) {
    showErrorNotification(result);
  }
}

/**
 * Moves selected file to trash bin.
 */
async function moveFileToTrash(filePath: String): Promise<void> {
  try {
    await ElMessageBox.confirm(t('moveFileToTrashBin', { filePath }));
    const result: string = await invoke('move_file_to_trash', { filePath: filePath });
    duplicateFiles.value = duplicateFiles.value.filter((p) => p.fileFullName != filePath);

    if (result) {
      showErrorNotification(result);
    } else {
      showSuccessNotification(t('fileMovedToTrashBin', { filePath }));
    }
  } catch {}
}
</script>

<template>
  <el-card>
    <template #header>
      <div class="header-item-container">
        <div class="header-item-label">MD5:</div>
        <div class="info">{{ md5 }}</div>
      </div>
      <div style="height: 3px"></div>
      <div class="header-item-container">
        <div class="header-item-label">{{ t('size') }}:</div>
        <div class="info">{{ formatSize(files[0].size) }}</div>
      </div>
    </template>
    <el-table header-cell-class-name="table-header" :data="duplicateFiles" style="width: 100%">
      <el-table-column :label="t('action')" width="150">
        <template #default="scope">
          <el-button
            :icon="Document"
            @click="openPath(scope.row.fileFullName)"
            :title="t('openFile')"
            circle
          />
          <el-button
            :icon="FolderOpened"
            @click="openPath(scope.row.path)"
            :title="t('openDirectory')"
            circle
          />
          <el-button
            :icon="Delete"
            @click="moveFileToTrash(scope.row.fileFullName)"
            :title="t('recycleFile')"
            circle
          />
        </template>
      </el-table-column>
      <el-table-column prop="filename" :label="t('filename')" width="220">
        <template #default="scope">
          <div class="header-item-container">
            <img
              v-if="scope.row.iconBase64"
              :src="`data:image/png;base64,${scope.row.iconBase64}`"
              class="file-icon"
            />
            <span>{{ scope.row.filename }}</span>
          </div>
        </template>
      </el-table-column>
      <el-table-column prop="path" :label="t('path')" />
    </el-table>
    <div class="info" style="margin-top: 20px">
      {{ duplicateFiles.length }} {{ t('duplicates') }}
    </div>
  </el-card>
</template>

<style scoped>
.header-item-container {
  display: flex;
  flex-direction: row;
  align-items: center;
}

.header-item-label {
  font-size: 1rem;
  width: 40px;
  text-align: right;
  margin-right: 5px;
}

.file-icon {
  width: 20px;
  margin-right: 6px;
}

.info {
  font-size: 1rem;
  color: gray;
}

:deep(.table-header) {
  background-color: #faf8f8 !important;
}
</style>
